package com.camel.studyApp.beanFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class TestBeanFactory {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        beanFactory.registerBeanDefinition("myBeanDefinition", beanDefinition);

        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }

        // 给Beanfactory添加一些常用的后置处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

//        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
//            System.out.println(beanDefinitionName);
//        }
        /**
         * BeanFactory 后处理器的主要功能， 补充了一些bean的定义
         * 也是springbboot 基于注解的ioc的基本实现前提
         */
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(e -> {
            e.postProcessBeanFactory(beanFactory);
        });

        /**
         * 添加Bean后置处理器 针对Bean的生命周期的各个阶段提供拓展和补充， 例如 @Autowired @Resource ...
         */
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);

        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }

        /**
         * 预加载
         */
        beanFactory.preInstantiateSingletons();

        System.out.println("使用Bean");
        System.out.println(beanFactory.getBean(Bean1.class).getBean2());
        System.out.println(beanFactory.getBean(Bean1.class).getBean2().getBean1());
        System.out.println(beanFactory.getBean(Bean1.class).getBean2().getBean1().getBean2());

        /**
         * beanFactory
         * 不会主动添加BeanFactory后处理器
         * 不会主动添加 Bean后处理器
         * 不会主动初始化单例对象
         * 不会解析beanFactory 还不会解析 #{} 和 #{}
         *
         * bean后处理器会有排序的逻辑
         */
    }

    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }


    static class Bean1 {
        private static final Logger log = LoggerFactory.getLogger(Bean1.class);

        public Bean1() {
            log.error("构造函数 Bean1");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return bean2;
        }
    }

    static class Bean2 {
        private static final Logger log = LoggerFactory.getLogger(Bean2.class);

        public Bean2() {
            log.error("构造函数 Bean2");
        }

        @Autowired
        private Bean1 bean1;

        public Bean1 getBean1() {
            return bean1;
        }
    }
}
